package com.zmj.sy.mom.srv.aps.feign;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zmj.sy.mom.srv.aps.bean.dto.qms.*;
import com.zmj.sy.mom.srv.aps.bean.entity.base.BaseEntity;
import com.zmj.sy.mom.srv.aps.bean.entity.order.Order;
import com.zmj.sy.mom.srv.aps.bean.entity.order.OrderBom;
import com.zmj.sy.mom.srv.aps.bean.entity.order.OrderPhase;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.LogApi;
import com.zmj.sy.mom.srv.aps.mapper.LogApiMapper;
import com.zmj.sy.mom.srv.aps.mapper.OrderBomMapper;
import com.zmj.sy.mom.srv.aps.mapper.OrderPhaseMapper;
import com.zmj.sy.mom.srv.aps.utils.JsonUtils;
import com.zmj.sy.mom.srv.aps.utils.LogApiConstant;
import com.zmj.sy.mom.srv.aps.utils.MkHttpUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Component
public class QmsOldApiClient {

    private final OrderBomMapper orderBomMapper;

    private final OrderPhaseMapper orderPhaseMapper;

    private final ObjectMapper objectMapper;

    private final LogApiMapper logApiMapper;

    private final MkHttpUtils mkHttpUtils;

    private BiConsumer<LogApi, String> consumer = (LogApi logApi, String body)->{
        JsonNode jsonNode = JsonUtils.readTree(body);
        if (jsonNode.get("Succeeded").asBoolean()) {
            logApi.setSuccess(true);
        } else {
            logApi.setSuccess(false);
            logApi.setErrorMsg(jsonNode.get("Errors").asText());
        }
    };

    /**
     * 把BOM结构同步到质量系统
     * @param order
     */
    @SneakyThrows
    public void bomSync(Order order) {
        List<OrderBom> orderBomList = orderBomMapper.lambdaQuery().eq(OrderBom::getOrderId, order.getId()).list();

        List<OrderPhase> orderPhaseList = orderPhaseMapper.lambdaQuery().eq(OrderPhase::getOrderId, order.getId()).list();

        if(CollUtil.isEmpty(orderBomList)){
            log.info("没有订单需要同步!");
            return ;
        }

        // BOM同步
        pushBom(order, orderBomList);

        // 工序同步
        pushPhase(order, orderBomList, orderPhaseList);

    }
    public void plateWorkStart(String constructNo, String workPlaceName, String plateNo, String phaseCode, String nestId, String workers){
// "/TaskInfo/AddTaskByPlate";
        QMsOldPlateTask task = new QMsOldPlateTask();
        task.setPlateNo(plateNo);
        //根据钢板号查询对应的施工号
        task.setErpProductionCode(constructNo);
        task.setKittingNo(nestId);
        task.setWorkStationNo(workPlaceName);
        task.setOP_NO(phaseCode);
        if(StringUtils.isBlank(workers)){
            workers="Operator";
        }
        task.setOperator(workers);
        mkHttpUtils.postJson(LogApiConstant.QMS, LogApiConstant.QMS_PLATE_START, null, task, consumer);

    }
    public void plateWorkEnd(String constructNo, String workPlaceName, String plateNo, String phaseCode, String nestId, String workers){
        QMsOldPlateTask task = new QMsOldPlateTask();
        task.setPlateNo(plateNo);
        //根据钢板号查询对应的施工号
        task.setErpProductionCode(constructNo);
        task.setKittingNo(nestId);
        task.setWorkStationNo(workPlaceName);
        task.setOP_NO(phaseCode);
        if(StringUtils.isBlank(workers)){
            workers="Operator";
        }
        task.setOperator(workers);
        mkHttpUtils.postJson(LogApiConstant.QMS, LogApiConstant.QMS_PLATE_END, null, task, consumer);

    }

    /**
     * 零件开工
     * @param constructNo 施工号
     * @param stationCode 工位编号
     * @param plmId PLM物料号
     * @param phaseCode 工序编号
     * @param operator 开工人
     */
    public void partWorkStart(String constructNo, String stationCode, String plmId, String phaseCode, String operator){

        QmsOldPartWorkStartReqDto req = new QmsOldPartWorkStartReqDto();
        req.setErpProductionCode(constructNo);
        req.setPlmId(plmId);
        req.setWorkStationNo(stationCode);
        req.setOpNo(phaseCode);
        if(StringUtils.isBlank(operator)){
            operator="Operator";
        }
        req.setOperator(operator);

        mkHttpUtils.postJson(LogApiConstant.QMS, LogApiConstant.QMS_PART_START, null, req, consumer);

    }

    /**
     * 零件报工
     * @param constructNo 施工号
     * @param stationCode 工位编号
     * @param plmId PLM物料号
     * @param phaseCode 工序编号
     * @param operator 报工人
     * @param reportCount 报工数量
     * @param packageNo 报工托盘
     * @param startPackageNo 开工托盘
     */
    public void partWorkEnd(String constructNo, String stationCode, String plmId, String phaseCode, String operator, Integer reportCount, String packageNo, String startPackageNo){

        QmsOldPartWorkEndReqDto req = new QmsOldPartWorkEndReqDto();
        req.setErpProductionCode(constructNo);
        req.setPlmId(plmId);
        req.setWorkStationNo(stationCode);
        req.setOpNo(phaseCode);
        if(StringUtils.isBlank(operator)){
            operator="Operator";
        }
        req.setOperator(operator);
        req.setReportCount(reportCount);
        req.setPackageNo(packageNo);
        req.setStartPackageNo(startPackageNo);

        mkHttpUtils.postJson(LogApiConstant.QMS, LogApiConstant.QMS_PART_END, null, req, consumer);
    }

    /**
     * 组件开工
     * @param constructNo 施工号
     * @param stationCode 工位编号
     * @param plmId PLM物料号
     * @param phaseCode 工序编号
     * @param operator 开工人
     * @param uniqueCode 组件唯一号
     */
    public void assemblyWorkStart(String constructNo, String stationCode, String plmId, String phaseCode, String operator,String uniqueCode){

        QmsOldAssemblyWorkStartReqDto req = new QmsOldAssemblyWorkStartReqDto();
        req.setErpProductionCode(constructNo);
        req.setPlmId(plmId);
        req.setWorkStationNo(stationCode);
        req.setOpNo(phaseCode);
        if(StringUtils.isBlank(operator)){
            operator="Operator";
        }
        req.setOperator(operator);
        req.setSn(uniqueCode);

        mkHttpUtils.postJson(LogApiConstant.QMS, LogApiConstant.QMS_ASSEMBLY_START, null, req, consumer);
    }

    /**
     * 组件报工
     * @param constructNo 施工号
     * @param stationCode 工位编号
     * @param plmId PLM物料号
     * @param phaseCode 工序编号
     * @param operator 开工人
     * @param uniqueCode 组件唯一号
     */
    public void assemblyWorkEnd(String constructNo, String stationCode, String plmId, String phaseCode, String operator,String uniqueCode) {
        QmsOldAssemblyWorkEndReqDto req = new QmsOldAssemblyWorkEndReqDto();
        req.setErpProductionCode(constructNo);
        req.setPlmId(plmId);
        req.setWorkStationNo(stationCode);
        req.setOpNo(phaseCode);
        if(StringUtils.isBlank(operator)){
            operator="Operator";
        }
        req.setOperator(operator);
        req.setSn(uniqueCode);

        mkHttpUtils.postJson(LogApiConstant.QMS, LogApiConstant.QMS_ASSEMBLY_END, null, req, consumer);

    }




    public void pushPhase(Order order, List<OrderBom> orderBomList, List<OrderPhase> orderPhaseList) {
        Map<Integer, OrderBom> orderBomMap = orderBomList.stream().collect(Collectors.toMap(BaseEntity::getId, e -> e));

        List<QmsOldBomSyncPhaseReqDto> reqPhaseList = orderPhaseList.stream()
                .map(e -> {
                    QmsOldBomSyncPhaseReqDto r = new QmsOldBomSyncPhaseReqDto();
                    r.setPlmId(e.getMaterNo());
                    r.setProcessCode(e.getPhaseCode());
                    r.setSort(e.getPhaseSeq().toString());
                    r.setDrawingPath(orderBomMap.get(e.getBomId()).getDrawingPath());
                    r.setDrawingType("0");
                    r.setMesChainId(e.getId().toString());
                    r.setIsPublished("0");
                    return r;
                })
                .collect(Collectors.toList());

        Integer count = logApiMapper.lambdaQuery()
                .eq(LogApi::getReceiver, LogApiConstant.QMS)
                .eq(LogApi::getApiName, "工序同步")
                .eq(LogApi::getQueryParam, order.getId())
                .eq(LogApi::getSuccess, true)
                .count();

        String code = LogApiConstant.QMS_PHASE_ADD;

        if(count > 0){
            code = LogApiConstant.QMS_PHASE_UPDATE;
        }

        mkHttpUtils.postJson(LogApiConstant.QMS, code, order.getId().toString(), reqPhaseList, consumer);

    }

    public void pushBom(Order order, List<OrderBom> orderBomList) {
        OrderBom top = orderBomList.stream().filter(e -> e.getPid() == null).findFirst().orElseThrow(() -> new RuntimeException("没有找到顶级BOM!"));
        List<QmsOldBomSyncReqDto> reqDtoList = orderBomList.stream()
                .map(e -> {
                    QmsOldBomSyncReqDto bomSync = new QmsOldBomSyncReqDto();
                    bomSync.setPlmId(e.getPlmId());
                    bomSync.setMaterialCode(e.getErpCode());
                    bomSync.setMaterialType(e.getMaterType());
                    bomSync.setName(e.getMaterName());
                    bomSync.setProductCode(order.getConstructNo());
                    bomSync.setMaterialSource("0");
                    bomSync.setMaterialLevel(e.getLevel());
                    bomSync.setDrawingCode(e.getDrawing());
                    bomSync.setProductionCode(top.getPlmId());
                    bomSync.setAssPath(e.getAssemblyPath());
                    bomSync.setOrgCode("170");
                    bomSync.setIsPublished("0");
                    bomSync.setSn(e.getId().toString());

                    bomSync.setBomId(e.getId());
                    bomSync.setOrderId(order.getId());
                    bomSync.setLogApiId(null);
                    return bomSync;
                })
                .collect(Collectors.toList());

        Integer count = logApiMapper.lambdaQuery()
                .eq(LogApi::getReceiver, LogApiConstant.QMS)
                .eq(LogApi::getApiName, LogApiConstant.QMS_BOM_ADD)
                .eq(LogApi::getQueryParam, order.getId())
                .eq(LogApi::getSuccess, true)
                .count();
        String code = LogApiConstant.QMS_BOM_ADD;
        if(count > 0){
            code = LogApiConstant.QMS_BOM_UPDATE;
        }
        mkHttpUtils.postJson(LogApiConstant.QMS, code, order.getId().toString(), reqDtoList, consumer);
    }

}
